﻿#region Directives

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Crm.Services.Utility;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.ServiceModel.Description;
using System.Web;

#endregion Directives

namespace ConnectIntegrationHub.WebService.Common
{
    public class Routines
    {
        #region Private Constants

        public const Int32 baseYear = 2000;

        #endregion Private Constants

        #region Public Static Methods

        public static DateTime? getDateTimeFromString(Boolean monthDayYearFormat = false, Boolean FourDigitYear = false, String stringValue = null)
        {
            if (String.IsNullOrEmpty(stringValue))
            {
                return null;
            }

            if (monthDayYearFormat)
            {
                return
                   new DateTime(
                       System.Convert.ToInt32(stringValue.Substring(4, 4), System.Globalization.CultureInfo.CurrentCulture),
                       System.Convert.ToInt32(stringValue.Substring(0, 2), System.Globalization.CultureInfo.CurrentCulture),
                       System.Convert.ToInt32(stringValue.Substring(2, 2), System.Globalization.CultureInfo.CurrentCulture)
                   );
            }
            else if (FourDigitYear)
            {
                return
                   new DateTime(
                       System.Convert.ToInt32(stringValue.Substring(0, 4), System.Globalization.CultureInfo.CurrentCulture),
                       System.Convert.ToInt32(stringValue.Substring(4, 2), System.Globalization.CultureInfo.CurrentCulture),
                       System.Convert.ToInt32(stringValue.Substring(6, 2), System.Globalization.CultureInfo.CurrentCulture)
                   );
            }
            else
            {
                return
                    new DateTime(
                        baseYear + System.Convert.ToInt32(stringValue.Substring(0, 2), System.Globalization.CultureInfo.CurrentCulture),
                        System.Convert.ToInt32(stringValue.Substring(2, 2), System.Globalization.CultureInfo.CurrentCulture),
                        System.Convert.ToInt32(stringValue.Substring(4, 2), System.Globalization.CultureInfo.CurrentCulture)
                    );
                
            }            
        }

        public static TimeSpan? getTimeSpanFromString(String stringValue)
        {
            if (String.IsNullOrEmpty(stringValue))
            {
                return null;
            }
            return
                new TimeSpan(
                    System.Convert.ToInt32(stringValue.Substring(0, 2), System.Globalization.CultureInfo.CurrentCulture),
                    System.Convert.ToInt32(stringValue.Substring(2, 2), System.Globalization.CultureInfo.CurrentCulture),
                    System.Convert.ToInt32(stringValue.Substring(4, 2), System.Globalization.CultureInfo.CurrentCulture)
                );
        }

        public static Int32 getOptionSetValue(IOrganizationService _service, String entityName, String attributeName, String optionsetText)
        {
            int optionSetValue = 0;
            RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest();
            retrieveAttributeRequest.EntityLogicalName = entityName;
            retrieveAttributeRequest.LogicalName = attributeName;
            retrieveAttributeRequest.RetrieveAsIfPublished = true;

            RetrieveAttributeResponse retrieveAttributeResponse =
              (RetrieveAttributeResponse)_service.Execute(retrieveAttributeRequest);
            PicklistAttributeMetadata picklistAttributeMetadata =
              (PicklistAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;

            OptionSetMetadata optionsetMetadata = picklistAttributeMetadata.OptionSet;

            foreach (OptionMetadata optionMetadata in optionsetMetadata.Options)
            {
                if (optionMetadata.Label.UserLocalizedLabel.Label.ToLower() == optionsetText.ToLower())
                {
                    optionSetValue = optionMetadata.Value.Value;
                    return optionSetValue;
                }

            }
            return optionSetValue;
        }

        public static String getOptionSetText(IOrganizationService _service, String entityName, String attributeName, Int32 optionsetValue)
        {
            String optionsetText = string.Empty;
            
            RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest();
            retrieveAttributeRequest.EntityLogicalName = entityName;
            retrieveAttributeRequest.LogicalName = attributeName;
            retrieveAttributeRequest.RetrieveAsIfPublished = true;

            RetrieveAttributeResponse retrieveAttributeResponse =
              (RetrieveAttributeResponse)_service.Execute(retrieveAttributeRequest);
            PicklistAttributeMetadata picklistAttributeMetadata =
              (PicklistAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;

            OptionSetMetadata optionsetMetadata = picklistAttributeMetadata.OptionSet;

            foreach (OptionMetadata optionMetadata in optionsetMetadata.Options)
            {
                if (optionMetadata.Value == optionsetValue)
                {
                    optionsetText = optionMetadata.Label.UserLocalizedLabel.Label;
                    return optionsetText;
                }

            }
            return optionsetText;
        }

        public static String getAttributeString(Entity entity, String fieldName)
        {
            String result = String.Empty;
            if (entity.Attributes.Contains(fieldName))
            {
                result = entity.Attributes[fieldName] as String;
            }
            return result;
        }

        public static EntityReference getAttributeEntityReference(Entity entity, String fieldName)
        {
            EntityReference result = null;
            if (entity.Attributes.Contains(fieldName))
            {
                result = entity.Attributes[fieldName] as EntityReference;
            }
            return result;
        }

        public static Boolean getAttributeBoolean(Entity entity, String fieldName)
        {
            Boolean result = false;
            if (entity.Attributes.Contains(fieldName))
            {
                try
                {
                    result = System.Convert.ToBoolean(entity.Attributes[fieldName], System.Globalization.CultureInfo.CurrentCulture);
                }
                catch { }
            }
            return result;
        }

        public static Int32? getAttributeInteger(Entity entity, String fieldName)
        {
            Int32? result = null;
            if (entity.Attributes.Contains(fieldName))
            {
                try
                {
                    result = System.Convert.ToInt32(entity.Attributes[fieldName], System.Globalization.CultureInfo.CurrentCulture);
                }
                catch { }
            }
            return result;
        }

        public static DateTime? getAttributeDateTime(Entity entity, String fieldName)
        {
            DateTime? result = null;
            if (entity.Attributes.Contains(fieldName))
            {
                try
                {
                    result = System.Convert.ToDateTime(entity.Attributes[fieldName], System.Globalization.CultureInfo.CurrentCulture);
                }
                catch { }
            }
            return result;
        }

        public static Decimal? getAttributeDecimal(Entity entity, String fieldName)
        {
            Decimal? result = null;
            if (entity.Attributes.Contains(fieldName))
            {
                try
                {
                    result = ((Microsoft.Xrm.Sdk.Money)(entity.Attributes[fieldName])).Value;
                }
                catch { }
            }
            return result;
        }

        public static Int32? getAttributeOptionSetInteger(Entity entity, String fieldName)
        {
            Int32? result = null;
            if (entity.Attributes.Contains(fieldName))
            {
                try
                {
                    result = ((Microsoft.Xrm.Sdk.OptionSetValue)(entity.Attributes[fieldName])).Value;
                }
                catch { }
            }
            return result;
        }

        public static String getDirectory(String folderName)
        {
            String sTempDirectory = AppDomain.CurrentDomain.BaseDirectory + folderName + @"\";
            if (!System.IO.Directory.Exists(sTempDirectory))
            {
                System.IO.Directory.CreateDirectory(sTempDirectory);
            }
            return sTempDirectory;
        }

        public static String getTempDirectory()
        {
            return getDirectory("Temp");
        }

        public static Boolean getDebugMode()
        {
            var value = ConfigurationManager.AppSettings["DebugMode"];
            if (!value.IsNullOrEmpty())
            {
                return Convert.ToBoolean(value, System.Globalization.CultureInfo.CurrentCulture);
            }
            return false;
        }

        public static String getCRMConfigurationName()
        {
            return ConfigurationManager.AppSettings["CRMConfigurationName"];
        }

        public static String getCRMOrganizationUri()
        {
            return ConfigurationManager.AppSettings["CRMOrganizationUri"];
        }

        public static Guid? getCRMApplicationId()
        {
            Guid? result = null;
            var applicationId = ConfigurationManager.AppSettings["CRMApplicationId"];
            if (!String.IsNullOrEmpty(applicationId))
            {
                result = new Guid(applicationId);
            }
            return result;
        }

        public static String getCRMUserName()
        {
            return ConfigurationManager.AppSettings["CRMUserName"];
        }

        public static String getCRMPassword()
        {
            return ConfigurationManager.AppSettings["CRMPassword"];
        }

        public static ConnectIntegrationHub.WebService.CRM.Configuration.InstallationTypes getCRMInstallationType()
        {
            ConnectIntegrationHub.WebService.CRM.Configuration.InstallationTypes result = ConnectIntegrationHub.WebService.CRM.Configuration.InstallationTypes.OnPremise;
            var installationType = ConfigurationManager.AppSettings["CRMInstallationType"];
            if (!String.IsNullOrEmpty(installationType))
            {
                result =
                    (ConnectIntegrationHub.WebService.CRM.Configuration.InstallationTypes)
                        System.Convert.ToInt32(
                            installationType,
                            System.Globalization.CultureInfo.CurrentCulture
                        );
            }
            return result;
        }

        #endregion Public Static Methods
    }
}